package cn.fintecher.pangolin.service.dataimp.task;

import cn.fintecher.pangolin.common.enums.*;
import cn.fintecher.pangolin.common.model.UserModel;
import cn.fintecher.pangolin.common.utils.ZWDateUtil;
import cn.fintecher.pangolin.entity.elastic.DataImportRecord;
import cn.fintecher.pangolin.entity.elastic.StopCaseModel;
import cn.fintecher.pangolin.entity.mysql.*;
import cn.fintecher.pangolin.service.dataimp.elastic.DataImportRecordElastic;
import cn.fintecher.pangolin.service.dataimp.repository.AssistCaseRepository;
import cn.fintecher.pangolin.service.dataimp.repository.CaseInfoRepository;
import cn.fintecher.pangolin.service.dataimp.repository.ProcessApplicationRepository;
import cn.fintecher.pangolin.service.dataimp.service.BaseService;
import cn.fintecher.pangolin.common.utils.RepositoryUtil;
import org.apache.commons.collections4.IterableUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * @Auther: xiaqun
 * @Description:
 * @Date: 16:18 2019/10/15
 */

@Service("confirmStopTask")
@Transactional
public class ConfirmStopTask {
    private static final Logger log = LoggerFactory.getLogger(ConfirmLeaveTask.class);

    @Autowired
    private DataImportRecordElastic dataImportRecordElastic;

    @Autowired
    private CaseInfoRepository caseInfoRepository;

    @Autowired
    private BaseService baseService;

    @Autowired
    private AssistCaseRepository assistCaseRepository;

    @Autowired
    private ProcessApplicationRepository processApplicationRepository;

    @Autowired
    private ConfirmStopFuture confirmStopFuture;

    /**
     * 留案导入确认
     */
    @Async
    public void confirmStop(List<StopCaseModel> models, UserModel userModel, DataImportRecord record) {
        //创建任务集合
        List<CompletableFuture<List<CaseInfo>>> list = new ArrayList<>();
        //分页处理信息
        int pageSize = 2000;
        int pageNumber = (int) Math.ceil((double) models.size() / (double) pageSize);
        for (int i = 0; i < pageNumber; i++) {
            List<StopCaseModel> stopCaseModels = models.stream().skip(i * pageSize).limit(pageSize).collect(Collectors.toList());
            CompletableFuture<List<CaseInfo>> task = confirmStopFuture.processStop(stopCaseModels);
            list.add(task);
        }
        List<CaseInfo> caseInfos = new ArrayList<>();
        try {
            for (CompletableFuture<List<CaseInfo>> future : list) {
                List<CaseInfo> caseInfoList = future.get();
                caseInfos.addAll(caseInfoList);
            }
            if (!caseInfos.isEmpty()) {
                RepositoryUtil.saveData(caseInfoRepository, caseInfos);
                List<String> caseIds = new ArrayList<>();
                caseInfos.forEach(e -> caseIds.add(e.getId()));
                //处理协催案件
                Iterable<AssistCase> assistCaseIterable = assistCaseRepository.findAll(QAssistCase.assistCase.caseId.in(caseIds)
                        .and(QAssistCase.assistCase.assistStatus.eq(AssistStatus.ASSIST_COLLECTING)).or(QAssistCase.assistCase.assistStatus.eq(AssistStatus.ASSIST_WAIT_ASSIGN)));
                List<AssistCase> assistCases = IterableUtils.toList(assistCaseIterable);
                assistCases.forEach(assistCase -> assistCase.setAssistStatus(AssistStatus.ASSIST_COMPLETED));
                RepositoryUtil.saveData(assistCaseRepository, assistCases);
                //处理审批流程
                Iterable<ProcessApplication> processApplicationIterable = processApplicationRepository.findAll(QProcessApplication.processApplication.caseId.in(caseIds)
                        .and(QProcessApplication.processApplication.approvalStage.eq(ApprovalStage.WAIT_APPROVAL).or(QProcessApplication.processApplication.approvalStage.eq(ApprovalStage.BEING_APPROVAL))));
                List<ProcessApplication> processApplications = IterableUtils.toList(processApplicationIterable);
                processApplications.forEach(processApplication -> {
                    processApplication.setApprovalStage(ApprovalStage.APPROVAL_CANCEL);
                    processApplication.getProcessFlowNodes().forEach(processFlowNode -> {
                        processFlowNode.setApprovedResult(ApprovalResult.APPROVED_REJECT);
                        processFlowNode.setApprovalStatus(ApprovalStatus.APPROVED_COMPLETED);
                    });
                });
                RepositoryUtil.saveData(processApplicationRepository, processApplications);
            }
            //更新导入结果状态
            record.setStatus(ImportDataExcelStatus.CONFIRMED);
            record.process(userModel.getRealName(), ZWDateUtil.getNowDateTime());
            dataImportRecordElastic.save(record);
        } catch (InterruptedException | ExecutionException e) {
            log.error(e.getMessage(), e);
            record.setStatus(ImportDataExcelStatus.UN_CONFIRMED);
            record.process(userModel.getRealName(), ZWDateUtil.getNowDateTime());
            dataImportRecordElastic.save(record);
        } finally {
            baseService.sendMsg(MessageType.IMPORT_END_CONFIRMED, userModel);
        }
    }
}
